{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Environment Wrapper Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "The credits for the code used in this chapter goes to <a href='https://github.com/spiglerg/DQN_DDQN_Dueling_and_DDPG_Tensorflow'>Giacomo Spigler's github repo </a> Throughout this chapter, code is explained each and every line. For a complete structured code check  <a href='https://github.com/spiglerg/DQN_DDQN_Dueling_and_DDPG_Tensorflow'> \n",
    "this</a> github repo. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First we will import all the necessary libaries,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import gym\n",
    "from gym.spaces import Box\n",
    "from scipy.misc import imresize\n",
    "import random\n",
    "import cv2\n",
    "import time\n",
    "import logging\n",
    "import os\n",
    "import sys"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " We define the Class EnvWrapper and define some of the environment wrapper functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class EnvWrapper:\n",
    "\n",
    "\n",
    "    # First we define the __init__ method and initialize variables\n",
    "\n",
    "    def __init__(self, env_name, debug=False):\n",
    "        \n",
    "\n",
    "        # environment name\n",
    "        self.env_name = env_name\n",
    "        \n",
    "        # initialize the gym environment\n",
    "        self.env = gym.make(env_name)\n",
    "\n",
    "        # get the action space\n",
    "        self.action_space = self.env.action_space\n",
    "\n",
    "        # get the observation space\n",
    "        self.observation_space = Box(low=0, high=255, shape=(84, 84, 4))  \n",
    "\n",
    "        # initialize frame_num for storing the frame count\n",
    "        self.frame_num = 0\n",
    "\n",
    "        # For recording the game screen\n",
    "        self.monitor = self.env.monitor\n",
    "\n",
    "        # initialize frames\n",
    "        self.frames = np.zeros((84, 84, 4), dtype=np.uint8)\n",
    "\n",
    "        # initialize a boolean called debug when set true last few frames will be displayed\n",
    "        self.debug = debug\n",
    "\n",
    "        if self.debug:\n",
    "            cv2.startWindowThread()\n",
    "            cv2.namedWindow(\"Game\")\n",
    "\n",
    "\n",
    "    # we define the function called step where we perform some action in the \n",
    "    # environment, receive reward and move to the next state \n",
    "    # step function will take the current state as input and returns the preprocessed frame as next state\n",
    "\n",
    "    def step(self, a):\n",
    "        ob, reward, done, xx = self.env.step(a)\n",
    "        return self.process_frame(ob), reward, done, xx\n",
    "\n",
    "\n",
    "    # We define the helper function called reset for resetting the environment\n",
    "    # after resetting it will return the preprocessed game screen\n",
    "    \n",
    "    def reset(self):\n",
    "        self.frame_num = 0\n",
    "        return self.process_frame(self.env.reset())\n",
    "\n",
    "\n",
    "    # next we define another helper function for rendering the environment\n",
    "    def render(self):\n",
    "        return self.env.render()\n",
    "\n",
    "\n",
    "    # now we define the function called process_frame for preprocessing the frame\n",
    "    \n",
    "    def process_frame(self, frame):\n",
    "\n",
    "        # convert the image to gray\n",
    "        state_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n",
    "        \n",
    "        # change the size\n",
    "        state_resized = cv2.resize(state_gray,(84,110))\n",
    "        \n",
    "        # resize\n",
    "        gray_final = state_resized[16:100,:]\n",
    "\n",
    "\n",
    "        if self.frame_num == 0:\n",
    "            self.frames[:, :, 0] = gray_final\n",
    "            self.frames[:, :, 1] = gray_final\n",
    "            self.frames[:, :, 2] = gray_final\n",
    "            self.frames[:, :, 3] = gray_final\n",
    "\n",
    "        else:\n",
    "            self.frames[:, :, 3] = self.frames[:, :, 2]\n",
    "            self.frames[:, :, 2] = self.frames[:, :, 1]\n",
    "            self.frames[:, :, 1] = self.frames[:, :, 0]\n",
    "            self.frames[:, :, 0] = gray_final\n",
    "\n",
    "        \n",
    "        # increment the frame_num counter\n",
    "\n",
    "        self.frame_num += 1\n",
    "\n",
    "        if self.debug:\n",
    "            cv2.imshow('Game', gray_final)\n",
    "\n",
    "        return self.frames.copy()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:universe]",
   "language": "python",
   "name": "conda-env-universe-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
